#include "capture.h"

#define MAX_PRINT 80
#define MAX_LINE 16

/*****************************************************************************/
/*                                                                           */
/* CaptureThread                                                             */
/*                                                                           */
/*****************************************************************************/
DWORD WINAPI CaptureThread(LPVOID lpParam)
{
  char* strDevice;
  pcap_if_t *alldevs;
  pcap_if_t *d;
  char errbuf[PCAP_ERRBUF_SIZE];
  int i;

  pcap_findalldevs(&alldevs, errbuf);
  
  /* Jump to the selected adapter */
//  for(d=alldevs, i=0; i<1; i++)     // tablet
  for(d=alldevs, i=0; i<0; i++)     // work laptop
	  d=d->next;
  
  strDevice = d->name;

  //StartCapture(strDevice, "C:\\Brian\\test.cap", "http.host == ""api-na-pad.gungho.jp""");
  StartCapture(strDevice, "C:\\Brian\\test.cap", NULL);

  return 0;
}

/*****************************************************************************/
/*                                                                           */
/* StartCapture                                                              */
/*                                                                           */
/*****************************************************************************/
void StartCapture(char* strDevice, char* strFilename, char* strFilter)
{
  char errbuf[PCAP_ERRBUF_SIZE];
  pcap_dumper_t *dumpfile;
  struct bpf_program fcode;
  bpf_u_int32 NetMask;
  int res;
  struct pcap_pkthdr *header;
  const u_char *pkt_data;

  // open a capture from the network
  if (strDevice != NULL)
  {
    if ((fp = pcap_open_live(strDevice,
                             1514,      /*snaplen*/
                             0,         /*flags*/
                             20,        /*read timeout*/
                             errbuf)
                             ) == NULL)
    {
      fprintf(stderr,"\nUnable to open the adapter.\n");
      return;
    }
  }

  if (strFilter != NULL)
  {
    // We should loop through the adapters returned by the pcap_findalldevs_ex()
    // in order to locate the correct one.
    //
    // Let's do things simpler: we suppose to be in a C class network ;-)
    NetMask=0xffffff;

    //compile the filter
    if(pcap_compile(fp, &fcode, strFilter, 1, NetMask) < 0)
    {
      fprintf(stderr,"\nError compiling filter: wrong syntax.\n");
      return;
    }

    //set the filter
    if(pcap_setfilter(fp, &fcode)<0)
    {
      fprintf(stderr,"\nError setting the filter\n");
      return;
    }
  }

  //open the dump file
  if (strFilename != NULL)
  {
    dumpfile = pcap_dump_open(fp, strFilename);
    
    if (dumpfile == NULL)
    {
      fprintf(stderr,"\nError opening output file\n");
      return;
    }
  }

  //start the capture
  while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0)
  {
    if(res == 0)
      /* Timeout elapsed */
      continue;

    //save the packet on the dump file
    pcap_dump((unsigned char *) dumpfile, header, pkt_data);

    //add the packet to the list
    AddPacketToList(header, pkt_data);
  }
}

/*****************************************************************************/
/*                                                                           */
/* OpenCapture                                                               */
/*                                                                           */
/*****************************************************************************/
void OpenCapture(char* strFilename)
{
  char errbuf[PCAP_ERRBUF_SIZE];
  int res;
  struct pcap_pkthdr *header;
  const u_char *pkt_data;

  // open the file
  if ((fp = pcap_open_offline(strFilename,
                              errbuf)
                             ) == NULL)
  {
    fprintf(stderr,"\nUnable to open the file.\n");
    return;
  }

  //start the capture
  while((res = pcap_next_ex( fp, &header, &pkt_data)) >= 0)
  {
    if(res == 0)
      /* Timeout elapsed */
      continue;

    //add the packet to the list
    AddPacketToList(header, pkt_data);
  }
}

/*****************************************************************************/
/*                                                                           */
/* AddPacketToList                                                           */
/*                                                                           */
/*****************************************************************************/
void AddPacketToList(pcap_pkthdr *header, const u_char *pkt_data)
{
  PACKET packetToAdd;
  const u_char* strFound;
  char strTemp[100];
  int nPosition, i;

  strFound = strnstr(pkt_data, (const u_char*)"api.php?action=", (int)header->len);

  if (strFound != NULL)
  {
    packetToAdd.bIncludeInListBox = true;

    nPosition = strFound - pkt_data;
    i = 0;
    while (pkt_data[nPosition + i] != '&')
    {
      strTemp[i] = pkt_data[nPosition + i];
      i++;
    }
	  strTemp[i] = 0;
    packetToAdd.strPacketType = strTemp + 15;
  }
  else
  {
    packetToAdd.bIncludeInListBox = false;
    packetToAdd.strPacketType = "data";
  }

  packetToAdd.nPacketNo = PacketList.GetCount() + 1;
  packetToAdd.nPacketLen = (int)header->len;
  packetToAdd.tPacketTime = CTime(header->ts.tv_sec);
  packetToAdd.nSourcePort = (pkt_data[34] << 8) + pkt_data[35];
  if (packetToAdd.nSourcePort == 80)
    packetToAdd.nSourcePort = (pkt_data[36] << 8) + pkt_data[37];

  CopyBuffer(packetToAdd.strPacketData, pkt_data, packetToAdd.nPacketLen);

  PacketList.AddTail(packetToAdd);
}

